#pragma once
#include<iostream>
#include<vector>
#include<semaphore.h>

template<class T>
class RingQueue
{
    const static int cap = 8;
public:
    RingQueue(const int cap = cap)
    :queue(cap)
    ,ProducterStep(0)
    ,ConsumerStep(0)
    {
        sem_init(&semSpace,0,cap);
        sem_init(&semProduct,0,0);
    }

    ~RingQueue()
    {
        sem_destroy(&semSpace);
        sem_destroy(&semProduct);
        delete queue;
    }

    void Push(const T& data)
    {
        sem_wait(&semSpace);
        queue[ProducterStep++] = data;
        ProducterStep%=cap;
        sem_post(&semProduct);
    }

    void Pop(T* data)
    {
        sem_wait(&semProduct);
        *data = queue[ConsumerStep++];
        ConsumerStep%=cap;
        sem_post(&semSpace);
    }

private:
    std::vector<T> queue;
    int _cap;    //循环队列容量
    sem_t semSpace;
    sem_t semProduct;
    int ConsumerStep;
    int ProducterStep;
};

